﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Afru;

namespace Afru
{
    public class MouseManager : Component
    {
        #region Variables

        public MouseState currentmouse;
        public MouseState oldmouse;
        public Vector2 Position;

        //This rectangle will be used to track mouse clicks
        public Rectangle clickRectangle;

        public bool leftIsHeld;
        public bool middleIsHeld;
        public bool rightIsHeld;

        private int screenwidth, screenheight;

        public float scrollWheelValue;
        private double time;
        private GameTime gametime;
        public bool clickedonce;
        #endregion

        #region Constructor

        public MouseManager(Vector2 ScreenDimensions)
        {
            currentmouse = new MouseState();
            oldmouse = new MouseState();
            Position = new Vector2(ScreenDimensions.X / 2, ScreenDimensions.Y / 2);
            clickRectangle = new Rectangle((int)Position.X, (int)Position.Y, 3, 3);
            leftIsHeld = false;
            screenwidth = (int)ScreenDimensions.X;
            screenheight = (int)ScreenDimensions.Y;
        }

        #endregion

        #region Class Functions

        #region Left Clicked
        /// <summary>
        /// Use this to determine if the left button was clicked
        /// </summary>
        /// <returns>if the left button was clicked</returns>
        public bool LeftClicked()
        {
            if (currentmouse.LeftButton == ButtonState.Pressed
                && oldmouse.LeftButton == ButtonState.Released)
            {
                clickedonce = true;
                time = gametime.TotalGameTime.TotalSeconds + .5f;
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region Left Double Clicked

        /// <summary>
        /// Use this to determine if the left button was
        /// double clicked
        /// </summary>
        /// <returns>If the left button was double clicked</returns>
        public bool DoubleClick()
        {
            if (clickedonce)
            {
                if (currentmouse.LeftButton == ButtonState.Pressed
                && oldmouse.LeftButton == ButtonState.Released)
                {
                    clickedonce = false;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        #endregion

        #region Left Held
        /// <summary>
        /// Use this to determine if the left button is being held
        /// The tricky part is figuring out the difference
        /// between a drag and a long click.
        ///
        /// What we're doing is testing if we already determined
        /// if it's already being held, or if it's being held and
        /// it's been moved.
        /// Else we assume it's a long click.
        /// </summary>
        /// <returns>If the button is being held</returns>
        public bool LeftHeld()
        {
            if (currentmouse.LeftButton == ButtonState.Pressed
                && oldmouse.LeftButton == ButtonState.Pressed
                && leftIsHeld == true)
            {
                return true;
            }
            else if ((currentmouse.LeftButton == ButtonState.Pressed
                && oldmouse.LeftButton == ButtonState.Pressed) &&
                (currentmouse.X != oldmouse.X || currentmouse.Y != oldmouse.Y))
            {
                leftIsHeld = true;
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        // TODO Middle click in mouse manager

        // TODO Middle double click in mouse manager

        #region Middle Held
        /// <summary>
        /// Use this to determine if the middle button is being held
        /// The tricky part is figuring out the difference
        /// between a drag and a long click.
        ///
        /// What we're doing is testing if we already determined
        /// if it's already being held, or if it's being held and
        /// it's been moved.
        /// Else we assume it's a long click.
        /// </summary>
        /// <returns>If the button is being held</returns>
        public bool MiddleHeld()
        {
            if (currentmouse.MiddleButton == ButtonState.Pressed
                && oldmouse.MiddleButton == ButtonState.Pressed
                && leftIsHeld == true)
            {
                return true;
            }
            else if ((currentmouse.MiddleButton == ButtonState.Pressed
                && oldmouse.MiddleButton == ButtonState.Pressed) &&
                (currentmouse.X != oldmouse.X || currentmouse.Y != oldmouse.Y))
            {
                middleIsHeld = true;
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        // TODO Middle click in mouse manager

        // TODO Middle double click in mouse manager

        #region Right Clicked
        /// <summary>
        /// Use this to determine if the right button is
        /// being held
        /// </summary>
        /// <returns>If the right button was clicked</returns>
        public bool RightClick()
        {
            if (currentmouse.RightButton == ButtonState.Pressed
                && oldmouse.RightButton == ButtonState.Released)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        // TODO Right click in mouse manager

        #region Right Held
        /// <summary>
        /// Use this to determine if the right button is being held
        /// The tricky part is figuring out the difference
        /// between a drag and a long click.
        ///
        /// What we're doing is testing if we already determined
        /// if it's already being held, or if it's being held and
        /// it's been moved.
        /// Else we assume it's a long click.
        /// </summary>
        /// <returns>If the button is being held</returns>
        public bool RightHeld()
        {
            if (currentmouse.RightButton == ButtonState.Pressed
                && oldmouse.RightButton == ButtonState.Pressed
                && rightIsHeld == true)
            {
                return true;
            }
            else if ((currentmouse.RightButton == ButtonState.Pressed
                && oldmouse.RightButton == ButtonState.Pressed) &&
                (currentmouse.X != oldmouse.X || currentmouse.Y != oldmouse.Y))
            {
                rightIsHeld = true;
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        

        #endregion

        #region Overrriden Functions

        protected override void Load()
        {
            currentmouse = new MouseState();
            oldmouse = new MouseState();
            base.Load();
        }

        public override void Update()
        {
            #region Set Position

            oldmouse = currentmouse;
            currentmouse = Mouse.GetState();
            Position.X = currentmouse.X;
            Position.Y = currentmouse.Y;

 
            if (clickedonce && time < ParentEngine.GameTime.TotalGameTime.TotalSeconds)
            {
                clickedonce = false;
            }
            //This is to keep our mouse on the screen
            if (Position.X < 0)
            {
                Position.X = 0;
            }
            else if (Position.X > screenwidth)
            {
                Position.X = screenwidth;
            }
            if (Position.Y < 0)
            {
                Position.Y = 0;
            }
            else if (Position.Y > screenheight)
            {
                Position.Y = screenheight;
            }
            
            gametime = ParentEngine.GameTime;

            clickRectangle.X = (int)Position.X;
            clickRectangle.Y = (int)Position.Y;
            #endregion
 
            if (leftIsHeld == true)
            {
                if (currentmouse.LeftButton == ButtonState.Released)
                {
                    leftIsHeld = false;
                }
            }

            scrollWheelValue += currentmouse.ScrollWheelValue -
                oldmouse.ScrollWheelValue;

            base.Update();
        }
        #endregion

    }
}
